# -*- coding: utf-8 -*-
"""
Created on Sat Nov 14 16:10:46 2020

@author: 310
"""
import matplotlib.pyplot as plt
import numpy as np

def func(x,y):
    return y-2*x/y

def euler(x,y,h,f):
    return y+h*f(x,y)

def improved_euler(x,y,h,f):
    y_p=y+h*f(x,y)
    y_c=y+h*f(x+h,y_p)
    return (y_p+y_c)/2

def runge_kutta(x,y,h,f):
    k1=f(x,y)
    k2=f(x+0.5*h,y+0.5*k1*h)
    k3=f(x+0.5*h,y+0.5*k2*h)
    k4=f(x+h,y+k3*h)
    return y+(k1+2*k2+2*k3+k4)*h/6

def calculate(x_0,y_0,x_n,h,method,f):
    x=x_0
    y=y_0
    x_list=[]
    y_list=[]
    while x<x_n:
        y=method(x,y,h,f)
        x_list.append(x)
        y_list.append(y)
        x=x+h
    return x_list,y_list


x_0=0
y_0=1
h=0.01
x_n=1
raw_x=np.linspace(x_0,x_n,100)
raw_y=np.sqrt(1+2*raw_x)

euler_x,euler_y=calculate(x_0,y_0,x_n,h,euler,func)
improve_euler_x,improve_euler_y=calculate(x_0, y_0, x_n, h, improved_euler, func)
RK_x,RK_y=calculate(x_0, y_0, x_n, h, runge_kutta, func)

plt.plot(RK_x,RK_y,label="runger_kutta")
plt.plot(raw_x,raw_y,label="origin")
plt.legend()
plt.show()